home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / skullxbo.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  22KB  |  835 lines

  1. /***************************************************************************
  2.  
  3.     vidhrdw/skullxbo.c
  4.  
  5.     Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************
  8.  
  9.     Playfield encoding
  10.     ------------------
  11.         1 16-bit word is used
  12.  
  13.         Word 1:
  14.             Bit  15    = horizontal flip
  15.             Bits 11-14 = palette
  16.             Bits  0-12 = image index
  17.  
  18.  
  19.     Motion Object encoding
  20.     ----------------------
  21.         4 16-bit words are used
  22.  
  23.         Word 1:
  24.             Bit  15    = horizontal flip
  25.             Bits  0-14 = image index
  26.  
  27.         Word 2:
  28.             Bits  7-15 = Y position
  29.             Bits  0-3  = height in tiles (ranges from 1-16)
  30.  
  31.         Word 3:
  32.             Bits  3-10 = link to the next image to display
  33.  
  34.         Word 4:
  35.             Bits  6-14 = X position
  36.             Bit   4    = use current X position + 16 for next sprite
  37.             Bits  0-3  = palette
  38.  
  39.  
  40.     Alpha layer encoding
  41.     --------------------
  42.         1 16-bit word is used
  43.  
  44.         Word 1:
  45.             Bit  15    = horizontal flip
  46.             Bit  12-14 = palette
  47.             Bits  0-11 = image index
  48.  
  49. ***************************************************************************/
  50.  
  51. #include "driver.h"
  52. #include "machine/atarigen.h"
  53. #include "vidhrdw/generic.h"
  54.  
  55. #define XCHARS 42
  56. #define YCHARS 30
  57.  
  58. #define XDIM (XCHARS*16)
  59. #define YDIM (YCHARS*8)
  60.  
  61.  
  62. #define DEBUG_VIDEO 0
  63.  
  64.  
  65.  
  66. /*************************************
  67.  *
  68.  *    Structures
  69.  *
  70.  *************************************/
  71.  
  72. struct pf_overrender_data
  73. {
  74.     struct osd_bitmap *bitmap;
  75.     int mo_priority;
  76. };
  77.  
  78.  
  79.  
  80. /*************************************
  81.  *
  82.  *    Statics
  83.  *
  84.  *************************************/
  85.  
  86. static struct atarigen_pf_state pf_state;
  87.  
  88. static UINT16 *scroll_list;
  89.  
  90. static UINT8 latch_byte;
  91. static UINT16 mo_bank;
  92.  
  93. #if DEBUG_VIDEO
  94. static UINT8 show_colors;
  95. #endif
  96.  
  97.  
  98.  
  99. /*************************************
  100.  *
  101.  *    Prototypes
  102.  *
  103.  *************************************/
  104.  
  105. static const UINT8 *update_palette(void);
  106.  
  107. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  108. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  109. static void pf_check_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  110. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  111.  
  112. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  113. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  114.  
  115. #if DEBUG_VIDEO
  116. static int debug(void);
  117. #endif
  118.  
  119.  
  120.  
  121. /*************************************
  122.  *
  123.  *    Video system start
  124.  *
  125.  *************************************/
  126.  
  127. int skullxbo_vh_start(void)
  128. {
  129.     static struct atarigen_mo_desc mo_desc =
  130.     {
  131.         256,                 /* maximum number of MO's */
  132.         8,                   /* number of bytes per MO entry */
  133.         2,                   /* number of bytes between MO words */
  134.         0,                   /* ignore an entry if this word == 0xffff */
  135.         0, 0, 0xff,          /* link = (data[linkword] >> linkshift) & linkmask */
  136.         0                    /* reverse order */
  137.     };
  138.  
  139.     static struct atarigen_pf_desc pf_desc =
  140.     {
  141.         16, 8,                /* width/height of each tile */
  142.         64, 64                /* number of tiles in each direction */
  143.     };
  144.  
  145.     /* reset statics */
  146.     memset(&pf_state, 0, sizeof(pf_state));
  147.     latch_byte = 0;
  148.     mo_bank = 0;
  149.  
  150.     /* allocate the scroll list */
  151.     scroll_list = malloc(sizeof(UINT16) * 2 * YDIM);
  152.     if (!scroll_list)
  153.         return 1;
  154.  
  155.     /* initialize the playfield */
  156.     if (atarigen_pf_init(&pf_desc))
  157.     {
  158.         free(scroll_list);
  159.         return 1;
  160.     }
  161.  
  162.     /* initialize the motion objects */
  163.     if (atarigen_mo_init(&mo_desc))
  164.     {
  165.         free(scroll_list);
  166.         atarigen_pf_free();
  167.         return 1;
  168.     }
  169.  
  170.     return 0;
  171. }
  172.  
  173.  
  174.  
  175. /*************************************
  176.  *
  177.  *    Video system shutdown
  178.  *
  179.  *************************************/
  180.  
  181. void skullxbo_vh_stop(void)
  182. {
  183.     if (scroll_list)
  184.         free(scroll_list);
  185.     scroll_list = NULL;
  186.  
  187.     atarigen_pf_free();
  188.     atarigen_mo_free();
  189. }
  190.  
  191.  
  192.  
  193. /*************************************
  194.  *
  195.  *    Video data latch
  196.  *
  197.  *************************************/
  198.  
  199. WRITE_HANDLER( skullxbo_hscroll_w )
  200. {
  201.     /* update the playfield state */
  202.     pf_state.hscroll = (data >> 7) << 1;
  203.     atarigen_pf_update(&pf_state, cpu_getscanline());
  204. }
  205.  
  206.  
  207. WRITE_HANDLER( skullxbo_vscroll_w )
  208. {
  209.     /* adjust for the scanline we're currently on */
  210.     int scanline = cpu_getscanline();
  211.     if (scanline >= YDIM) scanline -= YDIM;
  212.  
  213.     /* update the playfield state */
  214.     pf_state.vscroll = ((data >> 7) - scanline) & 0x1ff;
  215.     atarigen_pf_update(&pf_state, scanline);
  216. }
  217.  
  218.  
  219.  
  220. /*************************************
  221.  *
  222.  *    Motion object bank handler
  223.  *
  224.  *************************************/
  225.  
  226. WRITE_HANDLER( skullxbo_mobmsb_w )
  227. {
  228.     mo_bank = (offset & 0x400) * 2;
  229. }
  230.  
  231.  
  232.  
  233. /*************************************
  234.  *
  235.  *    Playfield latch write handler
  236.  *
  237.  *************************************/
  238.  
  239. WRITE_HANDLER( skullxbo_playfieldlatch_w )
  240. {
  241.     latch_byte = data & 0xff;
  242. }
  243.  
  244.  
  245.  
  246. /*************************************
  247.  *
  248.  *    Playfield RAM write handler
  249.  *
  250.  *************************************/
  251.  
  252. WRITE_HANDLER( skullxbo_playfieldram_w )
  253. {
  254.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  255.     int newword = COMBINE_WORD(oldword, data);
  256.  
  257.     /* only update if changed */
  258.     if (oldword != newword)
  259.     {
  260.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  261.         atarigen_pf_dirty[(offset & 0x1fff) / 2] = 0xff;
  262.     }
  263.  
  264.     /* if we're writing the low byte, also write the upper */
  265.     if (offset < 0x2000)
  266.         skullxbo_playfieldram_w(offset + 0x2000, latch_byte);
  267. }
  268.  
  269.  
  270.  
  271. /*************************************
  272.  *
  273.  *    Periodic playfield updater
  274.  *
  275.  *************************************/
  276.  
  277. void skullxbo_scanline_update(int scanline)
  278. {
  279.     UINT16 *base = (UINT16 *)&atarigen_alpharam[((scanline / 8) * 64 + XCHARS) * 2];
  280.     int x;
  281.  
  282.     /* keep in range */
  283.     if ((UINT8 *)base >= &atarigen_alpharam[atarigen_alpharam_size])
  284.         return;
  285.  
  286.     /* update the MOs from the SLIP table */
  287.     atarigen_mo_update_slip_512(&atarigen_spriteram[mo_bank], pf_state.vscroll, scanline, &atarigen_alpharam[0xf80]);
  288.  
  289.     /* update the current parameters */
  290.     for (x = XCHARS; x < 64; x++)
  291.     {
  292.         UINT16 data = *base++;
  293.         UINT16 command = data & 0x000f;
  294.  
  295.         if (command == 0x0d)
  296.         {
  297.             /* a new vscroll latches the offset into a counter; we must adjust for this */
  298.             int offset = scanline;
  299.             if (offset >= YDIM) offset -= YDIM;
  300.             pf_state.vscroll = ((data >> 7) - offset) & 0x1ff;
  301.             atarigen_pf_update(&pf_state, scanline);
  302.         }
  303.     }
  304. }
  305.  
  306.  
  307.  
  308. /*************************************
  309.  *
  310.  *    Main refresh
  311.  *
  312.  *************************************/
  313.  
  314. void skullxbo_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  315. {
  316.     int i;
  317.  
  318. #if DEBUG_VIDEO
  319.     debug();
  320. #endif
  321.  
  322.     /* update the palette, and mark things dirty */
  323.     if (update_palette())
  324.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 4);
  325.  
  326.     /* set up the all-transparent overrender palette */
  327.     for (i = 0; i < 32; i++)
  328.         atarigen_overrender_colortable[i] = palette_transparent_pen;
  329.  
  330.     /* draw the playfield */
  331.     memset(atarigen_pf_visit, 0, 64*64);
  332.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  333.  
  334.     /* draw the motion objects */
  335.     atarigen_mo_process(mo_render_callback, bitmap);
  336.  
  337.     /* draw the alphanumerics */
  338.     {
  339.         const struct GfxElement *gfx = Machine->gfx[2];
  340.         int x, y, offs;
  341.  
  342.         for (y = 0; y < YCHARS; y++)
  343.             for (x = 0, offs = y * 64; x < XCHARS; x++, offs++)
  344.             {
  345.                 int data = READ_WORD(&atarigen_alpharam[offs * 2]);
  346.                 int code = (data & 0x7ff) ^ 0x400;
  347.                 int opaque = data & 0x8000;
  348.                 int color = (data >> 11) & 15;
  349.                 drawgfx(bitmap, gfx, code, color, 0, 0, 16 * x, 8 * y, 0, opaque ? TRANSPARENCY_NONE : TRANSPARENCY_PEN, 0);
  350.             }
  351.     }
  352.  
  353.     /* update onscreen messages */
  354.     atarigen_update_messages();
  355. }
  356.  
  357.  
  358.  
  359. /*************************************
  360.  *
  361.  *    Palette management
  362.  *
  363.  *************************************/
  364.  
  365. static const UINT8 *update_palette(void)
  366. {
  367.     UINT16 pf_map[16], al_map[16];
  368.     UINT32 mo_map[16];
  369.     const unsigned int *usage;
  370.     int i, j, x, y, offs;
  371.  
  372.     /* reset color tracking */
  373.     memset(mo_map, 0, sizeof(mo_map));
  374.     memset(pf_map, 0, sizeof(pf_map));
  375.     memset(al_map, 0, sizeof(al_map));
  376.     palette_init_used_colors();
  377.  
  378.     /* update color usage for the playfield */
  379.     atarigen_pf_process(pf_color_callback, pf_map, &Machine->drv->visible_area);
  380.  
  381.     /* update color usage for the mo's */
  382.     atarigen_mo_process(mo_color_callback, mo_map);
  383.  
  384.     /* update color usage for the alphanumerics */
  385.     usage = Machine->gfx[2]->pen_usage;
  386.     for (y = 0; y < YCHARS; y++)
  387.         for (x = 0, offs = y * 64; x < XCHARS; x++, offs++)
  388.         {
  389.             int data = READ_WORD(&atarigen_alpharam[offs * 2]);
  390.             int code = (data & 0x7ff) ^ 0x400;
  391.             int color = (data >> 11) & 15;
  392.             al_map[color] |= usage[code];
  393.         }
  394.  
  395.     /* rebuild the playfield palette */
  396.     for (i = 0; i < 16; i++)
  397.     {
  398.         UINT16 used = pf_map[i];
  399.         if (used)
  400.             for (j = 0; j < 16; j++)
  401.                 if (used & (1 << j))
  402.                     palette_used_colors[0x200 + i * 16 + j] = PALETTE_COLOR_USED;
  403.     }
  404.  
  405.     /* rebuild the motion object palette */
  406.     for (i = 0; i < 16; i++)
  407.     {
  408.         UINT32 used = mo_map[i];
  409.         if (used)
  410.         {
  411.             palette_used_colors[0x000 + i * 32 + 0] = PALETTE_COLOR_TRANSPARENT;
  412.             for (j = 1; j < 32; j++)
  413.                 if (used & (1 << j))
  414.                     palette_used_colors[0x000 + i * 32 + j] = PALETTE_COLOR_USED;
  415.         }
  416.     }
  417.  
  418.     /* rebuild the alphanumerics palette */
  419.     for (i = 0; i < 16; i++)
  420.     {
  421.         UINT16 used = al_map[i];
  422.         if (used)
  423.             for (j = 0; j < 4; j++)
  424.                 if (used & (1 << j))
  425.                     palette_used_colors[0x300 + i * 4 + j] = PALETTE_COLOR_USED;
  426.     }
  427.  
  428.     /* recalc */
  429.     return palette_recalc();
  430. }
  431.  
  432.  
  433.  
  434. /*************************************
  435.  *
  436.  *    Playfield palette
  437.  *
  438.  *************************************/
  439.  
  440. static void pf_color_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  441. {
  442.     const unsigned int *usage = Machine->gfx[1]->pen_usage;
  443.     UINT16 *colormap = (UINT16 *)param;
  444.     int x, y;
  445.  
  446.     /* standard loop over tiles */
  447.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  448.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  449.         {
  450.             int offs = x * 64 + y;
  451.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  452.             int data2 = READ_WORD(&atarigen_playfieldram[0x2000 + offs * 2]);
  453.             int code = data & 0x7fff;
  454.             int color = data2 & 15;
  455.             colormap[color] |= usage[code];
  456.  
  457.             /* also mark unvisited tiles dirty */
  458.             if (!atarigen_pf_visit[offs]) atarigen_pf_dirty[offs] = 0xff;
  459.         }
  460. }
  461.  
  462.  
  463.  
  464. /*************************************
  465.  *
  466.  *    Playfield rendering
  467.  *
  468.  *************************************/
  469.  
  470. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  471. {
  472.     const struct GfxElement *gfx = Machine->gfx[1];
  473.     struct osd_bitmap *bitmap = param;
  474.     int x, y;
  475.  
  476.     /* standard loop over tiles */
  477.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  478.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  479.         {
  480.             int offs = x * 64 + y;
  481.             int data2 = READ_WORD(&atarigen_playfieldram[0x2000 + offs * 2]);
  482.             int color = data2 & 15;
  483.  
  484.             if (atarigen_pf_dirty[offs] != color)
  485.             {
  486.                 int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  487.                 int code = data & 0x7fff;
  488.                 int hflip = data & 0x8000;
  489.  
  490.                 drawgfx(atarigen_pf_bitmap, gfx, code, color, hflip, 0, 16 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  491.                 atarigen_pf_dirty[offs] = color;
  492.  
  493. #if DEBUG_VIDEO
  494.                 if (show_colors)
  495.                 {
  496.                     drawgfx(atarigen_pf_bitmap, Machine->uifont, "0123456789ABCDEF"[color], 1, 0, 0, 16 * x + 4, 8 * y, 0, TRANSPARENCY_PEN, 0);
  497.                     drawgfx(atarigen_pf_bitmap, Machine->uifont, "0123456789ABCDEF"[color], 1, 0, 0, 16 * x + 6, 8 * y, 0, TRANSPARENCY_PEN, 0);
  498.                     drawgfx(atarigen_pf_bitmap, Machine->uifont, "0123456789ABCDEF"[color], 0, 0, 0, 16 * x + 5, 8 * y, 0, TRANSPARENCY_PEN, 0);
  499.                 }
  500. #endif
  501.             }
  502.  
  503.             /* track the tiles we've visited */
  504.             atarigen_pf_visit[offs] = 1;
  505.         }
  506.  
  507.     /* then blast the result */
  508.     x = -state->hscroll;
  509.     y = -state->vscroll;
  510.     copyscrollbitmap(bitmap, atarigen_pf_bitmap, 1, &x, 1, &y, clip, TRANSPARENCY_NONE, 0);
  511.  
  512.     /* also fill in the scroll list */
  513.     for (y = clip->min_y; y <= clip->max_y; y++)
  514.         if (y >= 0 && y < YDIM)
  515.         {
  516.             scroll_list[y * 2 + 0] = state->hscroll;
  517.             scroll_list[y * 2 + 1] = state->vscroll;
  518.         }
  519. }
  520.  
  521.  
  522.  
  523. /*************************************
  524.  *
  525.  *    Playfield overrender check
  526.  *
  527.  *************************************/
  528.  
  529. static const UINT16 overrender_matrix[4] =
  530. {
  531.     0xf000,
  532.     0xff00,
  533.     0x0ff0,
  534.     0x00f0
  535. };
  536.  
  537. static void pf_check_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  538. {
  539.     const unsigned int *usage = Machine->gfx[1]->pen_usage;
  540.     struct pf_overrender_data *overrender_data = param;
  541.     int mo_priority = overrender_data->mo_priority;
  542.     int x, y;
  543.  
  544.     /* bail if we've already decided */
  545.     if (mo_priority == -1)
  546.         return;
  547.  
  548.     /* standard loop over tiles */
  549.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  550.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  551.         {
  552.             int offs = x * 64 + y;
  553.             int data2 = READ_WORD(&atarigen_playfieldram[0x2000 + offs * 2]);
  554.             int color = data2 & 15;
  555.  
  556.             if (overrender_matrix[mo_priority] & (1 << color))
  557.             {
  558.                 int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  559.                 int code = data & 0x7fff;
  560.  
  561.                 if (usage[code] & 0xff00)
  562.                 {
  563.                     overrender_data->mo_priority = -1;
  564.                     return;
  565.                 }
  566.             }
  567.         }
  568. }
  569.  
  570.  
  571.  
  572. /*************************************
  573.  *
  574.  *    Playfield overrendering
  575.  *
  576.  *************************************/
  577.  
  578. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  579. {
  580.     const struct pf_overrender_data *overrender_data = param;
  581.     struct osd_bitmap *bitmap = overrender_data->bitmap;
  582.     int mo_priority = overrender_data->mo_priority;
  583.     const struct GfxElement *gfx = Machine->gfx[1];
  584.     int x, y;
  585.  
  586.     /* standard loop over tiles */
  587.     for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  588.     {
  589.         int sx = (16 * x - state->hscroll) & 0x3ff;
  590.         if (sx >= XDIM) sx -= 0x400;
  591.  
  592.         for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  593.         {
  594.             int offs = x * 64 + y;
  595.             int data2 = READ_WORD(&atarigen_playfieldram[0x2000 + offs * 2]);
  596.             int color = data2 & 15;
  597.             int sy = (8 * y - state->vscroll) & 0x1ff;
  598.             if (sy >= YDIM) sy -= 0x200;
  599.  
  600.             if (overrender_matrix[mo_priority] & (1 << color))
  601.             {
  602.                 int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  603.                 int code = data & 0x7fff;
  604.                 int hflip = data & 0x8000;
  605.  
  606.                 drawgfx(bitmap, gfx, code, color, hflip, 0, sx, sy, 0, TRANSPARENCY_PENS, 0x00ff);
  607.             }
  608.         }
  609.     }
  610. }
  611.  
  612.  
  613.  
  614. /*************************************
  615.  *
  616.  *    Motion object palette
  617.  *
  618.  *************************************/
  619.  
  620. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  621. {
  622.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  623.     UINT32 *colormap = param;
  624.     int code = data[1] & 0x7fff;
  625.     int color = data[2] & 0x000f;
  626.     int hsize = ((data[3] >> 4) & 7) + 1;
  627.     int vsize = (data[3] & 15) + 1;
  628.     int tiles = hsize * vsize;
  629.     UINT32 temp = 0;
  630.     int i;
  631.  
  632.     for (i = 0; i < tiles; i++)
  633.         temp |= usage[code++];
  634.     colormap[color] |= temp;
  635. }
  636.  
  637.  
  638.  
  639. /*************************************
  640.  *
  641.  *    Motion object rendering
  642.  *
  643.  *************************************/
  644.  
  645. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  646. {
  647.     struct GfxElement *gfx = Machine->gfx[0];
  648.     struct pf_overrender_data overrender_data;
  649.     struct osd_bitmap *bitmap = param;
  650.     struct rectangle pf_clip;
  651.  
  652.     /* determine the scroll offsets */
  653.     int scroll_scanline = (clip->min_y < 0) ? 0 : (clip->min_y > YDIM) ? YDIM : clip->min_y;
  654.     int xscroll = scroll_list[scroll_scanline * 2 + 0];
  655.     int yscroll = scroll_list[scroll_scanline * 2 + 1];
  656.  
  657.     /* extract data from the various words */
  658.     int code = data[1] & 0x7fff;
  659.     int hflip = data[1] & 0x8000;
  660.     int xpos = ((data[2] >> 7) << 1) - xscroll;
  661.     int color = data[2] & 0x000f;
  662.     int hsize = ((data[3] >> 4) & 7) + 1;
  663.     int vsize = (data[3] & 15) + 1;
  664.     int ypos = -(data[3] >> 7) - yscroll;
  665.     int priority = (data[2] >> 4) & 3;
  666.  
  667.     /* adjust for height */
  668.     ypos -= vsize * 8;
  669.  
  670.     /* adjust the final coordinates */
  671.     xpos &= 0x3ff;
  672.     ypos &= 0x1ff;
  673.     if (xpos >= XDIM) xpos -= 0x400;
  674.     if (ypos >= YDIM) ypos -= 0x200;
  675.  
  676.     /* determine the bounding box */
  677.     atarigen_mo_compute_clip_16x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  678.  
  679.     /* see if we're going to need to overrender */
  680.     overrender_data.mo_priority = priority;
  681.     atarigen_pf_process(pf_check_overrender_callback, &overrender_data, &pf_clip);
  682.  
  683.     /* simple case? */
  684.     if (overrender_data.mo_priority == priority)
  685.     {
  686.         /* just draw -- we have dominion over all */
  687.         atarigen_mo_draw_16x8(bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  688.     }
  689.  
  690.     /* otherwise, it gets a smidge trickier */
  691.     else
  692.     {
  693.         /* draw an instance of the object in all transparent pens */
  694.         atarigen_mo_draw_transparent_16x8(bitmap, gfx, code, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  695.  
  696.         /* and then draw it normally on the temp bitmap */
  697.         atarigen_mo_draw_16x8(atarigen_pf_overrender_bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_NONE, 0);
  698.  
  699.         /* overrender the playfield on top of that that */
  700.         overrender_data.mo_priority = priority;
  701.         overrender_data.bitmap = atarigen_pf_overrender_bitmap;
  702.         atarigen_pf_process(pf_overrender_callback, &overrender_data, &pf_clip);
  703.  
  704.         /* finally, copy this chunk to the real bitmap */
  705.         copybitmap(bitmap, atarigen_pf_overrender_bitmap, 0, 0, 0, 0, &pf_clip, TRANSPARENCY_THROUGH, palette_transparent_pen);
  706.     }
  707.  
  708. #if DEBUG_VIDEO
  709.     if (show_colors)
  710.     {
  711.         int tx = (pf_clip.min_x + pf_clip.max_x) / 2 - 3;
  712.         int ty = (pf_clip.min_y + pf_clip.max_y) / 2 - 4;
  713.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx - 2, ty - 2, 0, TRANSPARENCY_NONE, 0);
  714.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx + 2, ty - 2, 0, TRANSPARENCY_NONE, 0);
  715.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx - 2, ty + 2, 0, TRANSPARENCY_NONE, 0);
  716.         drawgfx(bitmap, Machine->uifont, ' ', 0, 0, 0, tx + 2, ty + 2, 0, TRANSPARENCY_NONE, 0);
  717.         drawgfx(bitmap, Machine->uifont, "0123456789ABCDEF"[priority], 0, 0, 0, tx, ty, 0, TRANSPARENCY_NONE, 0);
  718.     }
  719. #endif
  720. }
  721.  
  722.  
  723.  
  724. /*************************************
  725.  *
  726.  *    Debugging
  727.  *
  728.  *************************************/
  729.  
  730. #if DEBUG_VIDEO
  731.  
  732. static void mo_print(struct osd_bitmap *bitmap, struct rectangle *clip, UINT16 *data, void *param)
  733. {
  734.     int code = data[1] & 0x7fff;
  735.     int hsize = ((data[3] >> 4) & 7) + 1;
  736.     int vsize = (data[3] & 15) + 1;
  737.     int xpos = (data[2] >> 7);
  738.     int ypos = (data[3] >> 7);
  739.     int color = data[2] & 15;
  740.     int hflip = data[1] & 0x8000;
  741.     int priority = (data[2] >> 4) & 3;
  742.  
  743.     FILE *f = (FILE *)param;
  744.     fprintf(f, "P=%04X X=%03X Y=%03X SIZE=%Xx%X COL=%X FLIP=%X PRI=%X  -- DATA=%04X %04X %04X %04X\n",
  745.             code, xpos, ypos, hsize, vsize, color, hflip >> 15, priority, data[0], data[1], data[2], data[3]);
  746. }
  747.  
  748. static int debug(void)
  749. {
  750.     int hidebank = 0;
  751.     int new_show_colors;
  752.  
  753.     new_show_colors = keyboard_pressed(KEYCODE_CAPSLOCK);
  754.     if (new_show_colors != show_colors)
  755.     {
  756.         show_colors = new_show_colors;
  757.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 4);
  758.     }
  759.  
  760.     if (keyboard_pressed(KEYCODE_Q)) hidebank = 0;
  761.     if (keyboard_pressed(KEYCODE_W)) hidebank = 1;
  762.     if (keyboard_pressed(KEYCODE_E)) hidebank = 2;
  763.     if (keyboard_pressed(KEYCODE_R)) hidebank = 3;
  764.     if (keyboard_pressed(KEYCODE_T)) hidebank = 4;
  765.     if (keyboard_pressed(KEYCODE_Y)) hidebank = 5;
  766.     if (keyboard_pressed(KEYCODE_U)) hidebank = 6;
  767.     if (keyboard_pressed(KEYCODE_I)) hidebank = 7;
  768.  
  769.     if (keyboard_pressed(KEYCODE_A)) hidebank = 8;
  770.     if (keyboard_pressed(KEYCODE_S)) hidebank = 9;
  771.     if (keyboard_pressed(KEYCODE_D)) hidebank = 10;
  772.     if (keyboard_pressed(KEYCODE_F)) hidebank = 11;
  773.     if (keyboard_pressed(KEYCODE_G)) hidebank = 12;
  774.     if (keyboard_pressed(KEYCODE_H)) hidebank = 13;
  775.     if (keyboard_pressed(KEYCODE_J)) hidebank = 14;
  776.     if (keyboard_pressed(KEYCODE_K)) hidebank = 15;
  777.  
  778.     if (keyboard_pressed(KEYCODE_9))
  779.     {
  780.         static int count;
  781.         char name[50];
  782.         FILE *f;
  783.         int i;
  784.  
  785.         while (keyboard_pressed(KEYCODE_9)) { }
  786.  
  787.         sprintf(name, "Dump %d", ++count);
  788.         f = fopen(name, "wt");
  789.  
  790.         fprintf(f, "\n\nPalette RAM:\n");
  791.  
  792.         for (i = 0x000; i < 0x800; i++)
  793.         {
  794.             fprintf(f, "%04X ", READ_WORD(&paletteram[i*2]));
  795.             if ((i & 15) == 15) fprintf(f, "\n");
  796.             if ((i & 255) == 255) fprintf(f, "\n");
  797.         }
  798.  
  799.         fprintf(f, "\n\nMotion Objects (drawn)\n");
  800. /*        atarigen_mo_process(mo_print, f);*/
  801.  
  802.         fprintf(f, "\n\nMotion Objects\n");
  803.         for (i = 0; i < 0x200; i++)
  804.         {
  805.             fprintf(f, "   Object %02X:  P=%04X  Y=%04X  L=%04X  X=%04X\n",
  806.                     i,
  807.                     READ_WORD(&atarigen_spriteram[i*8+0]),
  808.                     READ_WORD(&atarigen_spriteram[i*8+2]),
  809.                     READ_WORD(&atarigen_spriteram[i*8+4]),
  810.                     READ_WORD(&atarigen_spriteram[i*8+6])
  811.             );
  812.         }
  813.  
  814.         fprintf(f, "\n\nPlayfield dump\n");
  815.         for (i = 0; i < atarigen_playfieldram_size / 4; i++)
  816.         {
  817.             fprintf(f, "%01X%04X ", READ_WORD(&atarigen_playfieldram[0x2000 + i*2]), READ_WORD(&atarigen_playfieldram[i*2]));
  818.             if ((i & 63) == 63) fprintf(f, "\n");
  819.         }
  820.  
  821.         fprintf(f, "\n\nAlpha dump\n");
  822.         for (i = 0; i < atarigen_alpharam_size / 2; i++)
  823.         {
  824.             fprintf(f, "%04X ", READ_WORD(&atarigen_alpharam[i*2]));
  825.             if ((i & 63) == 63) fprintf(f, "\n");
  826.         }
  827.  
  828.         fclose(f);
  829.     }
  830.  
  831.     return hidebank;
  832. }
  833.  
  834. #endif
  835.